package cate.game.pvp.minecraft;

import cate.game.framework.ModuleMan;
import cate.game.play.part.PlaySide;
import cate.game.pvp.minecraft.data.MinecraftPvpRecord;
import cate.game.res.MixRes;
import cate.game.role.Role;
import cate.game.role.RoleSnapshot;
import cate.game.role.farm.island.po.HeroState;
import cate.game.role.mail.Mail;
import cate.game.role.pvp.minecraft.msg.*;
import easy.java.dev.note.NoteClass;
import easy.java.practice.errorcode.EcResult;

import java.util.List;
import java.util.Optional;

@NoteClass("灵能矿洞-Game发送消息模块")
public class MinecraftMessagingModule extends ModuleMan {

    @Override
    public void initDependent() throws Exception {
        serverConnect();
    }

    /**
     * 服务器连接
     */
    public void serverConnect() {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_GAME_CONNECT,
                game.config.srvId);
    }

    /**
     * 玩家登录
     *
     * @param role 玩家
     */
    public void roleEnterSync(Role role) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_ROLE_ONLINE,
                new RoleSnapshot(role));
    }

    /**
     * 查看矿区概览
     *
     * @param role 角色
     */
    public void handleOverview(Role role) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_OVERVIEW,
                CrossOverviewParams.of(role));
    }

    /**
     * 查看单层信息
     *
     * @param role  角色
     * @param layer 层数
     */
    public void handleViewLayer(Role role, int layer) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_VIEW_LAYER,
                CrossViewLayerParams.of(role, layer));
    }

    /**
     * 查看我的点位信息
     *
     * @param role   玩家
     * @param detail 是否细节
     */
    public void handleViewMyPoints(Role role, boolean detail) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_VIEW_MY_POINTS,
                CrossViewMyPointsParams.of(role, detail));
    }

    /**
     * 查看矿点详细信息
     *
     * @param role  角色
     * @param layer 层数
     * @param tid   配置ID
     */
    public void handleViewPointDetail(Role role, int layer, int tid) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_VIEW_POINT_DETAIL,
                CrossViewPointDetailParams.of(role, layer, tid));
    }

    /**
     * 尝试发起战斗
     *
     * @param role  角色
     * @param layer 层数
     * @param tid   点位ID
     */
    public void tryFight(Role role, int layer, int tid) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_TRY_FIGHT,
                CrossTryFightPointParams.of(role, layer, tid));
    }

    /**
     * 战斗结果上报
     *
     * @param role       角色
     * @param layer      层数
     * @param tid        点位ID
     * @param playSides  玩家方数据
     * @param heroStates 对手剩余血量状态
     */
    public void fightResultReport(Role role,
                                  int layer,
                                  int tid,
                                  boolean win,
                                  long offensePower,
                                  long defensePower,
                                  List<PlaySide> playSides,
                                  List<HeroState> heroStates,
                                  MinecraftMineAreaFightResultResp resultResp) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_FIGHT_RESULT_REPORT,
                CrossFightResultReportParams.of(role,
                        layer,
                        tid,
                        win,
                        offensePower,
                        defensePower,
                        playSides,
                        heroStates,
                        resultResp));
    }

    /**
     * 领取挂机奖励
     *
     * @param role  角色UID
     * @param layer 层数
     * @param tid   配置ID
     */
    public void handleGetHangReward(Role role, int layer, int tid) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_GET_HANG_REWARD,
                CrossGetHangRewardParams.of(role, layer, tid));
    }

    /**
     * 矿点保护
     *
     * @param role  角色UID
     */
    public void handleProtectPoint(Role role) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_PROTECT_POINT,
                CrossProtectPointParams.of(role));
    }

    /**
     * 放弃矿点
     *
     * @param role  角色UID
     * @param layer 层数
     * @param tid   配置ID
     */
    public void handleGiveUpPoint(Role role, int layer, int tid) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_GIVE_UP_POINT,
                CrossGiveUpPointParams.of(role, layer, tid));
    }

    /**
     * 合服结算矿点
     *
     * @return 结算邮件
     */
    public List<CrossAddMail> mergeSettle() {
        return Optional.ofNullable(game.rpcSend().requestResponseCross(MinecraftInnerMsg.MC_MERGE_SETTLE,
                game.config.srvId,
                MinecraftMergeMails.class))
                .map(mmm -> mmm.mails)
                .orElse(null);
    }

    /**
     * 通知跨服GM功能
     *
     * @param role    角色
     * @param cmdType 命令
     * @param params  参数
     */
    public void sendGMParams(Role role, CrossGMCmdType cmdType, List<String> params) {
        game.rpcSend().fireAndForgetCross(MinecraftInnerMsg.MC_GM_CMD,
                CrossGMCmd.of(role, cmdType, params));
    }

    /**
     * 发送PVP记录到对应服务器
     *
     * @param srvId  服务器ID
     * @param record 记录
     */
    public void transferPvpRecord(int srvId, MinecraftPvpRecord record) {
        game.rpcSend().fireAndForgetGame(MinecraftInnerMsg.MC_TRANSFER_PVP_RECORD,
                srvId,
                record);
    }

    /**
     * 矿区GM指令
     */
    public enum CrossGMCmdType {
        NONE,
        HANG_REWARD_GENERATE,
        FORCE_SETTLE,
        CANCEL_LOCK,
        SAVE,
    }

    /**
     * 跨服角色占用信息
     */
    public static class CrossRoleUsedInfo {
        public String roleUid;
        public int srvId;
        public List<Integer> usedHallows;
        public List<Integer> usedHeroProtoIds;

        public static CrossRoleUsedInfo of(String roleUid,
                                           int srvId,
                                           List<Integer> usedHallows,
                                           List<Integer> usedHeroProtoIds) {
            CrossRoleUsedInfo info = new CrossRoleUsedInfo();
            info.roleUid = roleUid;
            info.srvId = srvId;
            info.usedHallows = usedHallows;
            info.usedHeroProtoIds = usedHeroProtoIds;
            return info;
        }
    }

    /**
     * 跨服矿区状态信息
     */
    public static class CrossMineAreaState {
        public boolean close;
        public long openTime;
        public long closeTime;

        public static CrossMineAreaState of(boolean close, long openTime, long closeTime) {
            CrossMineAreaState state = new CrossMineAreaState();
            state.close = close;
            state.openTime = openTime;
            state.closeTime = closeTime;
            return state;
        }
    }

    /**
     * 查看矿区概览 参数
     */
    public static class CrossOverviewParams {
        public String roleUid;
        public int srvId;

        public static CrossOverviewParams of(Role role) {
            CrossOverviewParams params = new CrossOverviewParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            return params;
        }
    }

    /**
     * 查看矿区概览 返回
     */
    public static class CrossOverviewBack {
        public String roleUid;
        public int srvId;
        public MinecraftMineAreaOverviewResp resp;

        public static CrossOverviewBack of(String roleUid, int srvId, MinecraftMineAreaOverviewResp resp) {
            CrossOverviewBack back = new CrossOverviewBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.resp = resp;
            return back;
        }
    }

    /**
     * 跨服查看单层数据 参数
     */
    public static class CrossViewLayerParams {
        public String roleUid;
        public int srvId;
        public int layer;

        public static CrossViewLayerParams of(Role role, int layer) {
            CrossViewLayerParams params = new CrossViewLayerParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            params.layer = layer;
            return params;
        }
    }

    /**
     * 跨服查看单层数据 返回
     */
    public static class CrossViewLayerBack {
        public String roleUid;
        public int srvId;
        public EcResult<MinecraftMineAreaLayerInfoResp> result;

        public static CrossViewLayerBack of(String roleUid, int srvId, EcResult<MinecraftMineAreaLayerInfoResp> result) {
            CrossViewLayerBack back = new CrossViewLayerBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.result = result;
            return back;
        }
    }

    /**
     * 查看我的点位信息 参数
     */
    public static class CrossViewMyPointsParams {
        public String roleUid;
        public int srvId;
        public boolean detail;

        public static CrossViewMyPointsParams of(Role role, boolean detail) {
            CrossViewMyPointsParams params = new CrossViewMyPointsParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            params.detail = detail;
            return params;
        }
    }

    /**
     * 查看我的点位信息 返回
     */
    public static class CrossViewMyPointsBack {
        public String roleUid;
        public int srvId;
        public MinecraftMineAreaMyPointsResp resp;

        public static CrossViewMyPointsBack of(String roleUid, int srvId, MinecraftMineAreaMyPointsResp resp) {
            CrossViewMyPointsBack back = new CrossViewMyPointsBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.resp = resp;
            return back;
        }
    }

    /**
     * 查看矿点详细信息 参数
     */
    public static class CrossViewPointDetailParams {
        public String roleUid;
        public int srvId;
        public int layer;
        public int tid;

        public static CrossViewPointDetailParams of(Role role, int layer, int tid) {
            CrossViewPointDetailParams params = new CrossViewPointDetailParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            params.layer = layer;
            params.tid = tid;
            return params;
        }
    }

    /**
     * 查看矿点详细信息 返回
     */
    public static class CrossViewPointDetailBack {
        public String roleUid;
        public int srvId;
        public EcResult<MinecraftMineAreaPointDetailResp> result;

        public static CrossViewPointDetailBack of(String roleUid, int srvId, EcResult<MinecraftMineAreaPointDetailResp> result) {
            CrossViewPointDetailBack back = new CrossViewPointDetailBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.result = result;
            return back;
        }
    }

    /**
     * 尝试发起跨服战斗 参数
     */
    public static class CrossTryFightPointParams {
        public RoleSnapshot roleSnapshot;
        public int layer;
        public int tid;

        public static CrossTryFightPointParams of(Role role, int layer, int tid) {
            CrossTryFightPointParams params = new CrossTryFightPointParams();
            params.roleSnapshot = new RoleSnapshot(role);
            params.layer = layer;
            params.tid = tid;
            return params;
        }
    }

    /**
     * 尝试发起跨服战斗 返回
     */
    public static class CrossTryFightPointBack {
        public String roleUid;
        public int srvId;
        public int layer;
        public int tid;
        public EcResult<Void> result;
        public List<PlaySide> playSides;
        public List<HeroState> heroStates;

        public static CrossTryFightPointBack of(String roleUid,
                                                int srvId,
                                                int layer,
                                                int tid,
                                                EcResult<Void> result,
                                                List<PlaySide> playSides,
                                                List<HeroState> heroStates) {
            CrossTryFightPointBack back = new CrossTryFightPointBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.layer = layer;
            back.tid = tid;
            back.result = result;
            back.playSides = playSides;
            back.heroStates = heroStates;
            return back;
        }
    }

    /**
     * 战斗结果上报 参数
     */
    public static class CrossFightResultReportParams {
        public RoleSnapshot roleSnapshot;
        public int layer;
        public int tid;
        public boolean win;
        public long offensePower;
        public long defensePower;
        public List<PlaySide> playSides;
        public List<HeroState> heroStates;
        public MinecraftMineAreaFightResultResp resultResp;

        public static CrossFightResultReportParams of(Role role,
                                                      int layer,
                                                      int tid,
                                                      boolean win,
                                                      long offensePower,
                                                      long defensePower,
                                                      List<PlaySide> playSides,
                                                      List<HeroState> heroStates,
                                                      MinecraftMineAreaFightResultResp resultResp) {
            CrossFightResultReportParams params = new CrossFightResultReportParams();
            params.roleSnapshot = new RoleSnapshot(role);
            params.layer = layer;
            params.tid = tid;
            params.win = win;
            params.offensePower = offensePower;
            params.defensePower = defensePower;
            params.playSides = playSides;
            params.heroStates = heroStates;
            params.resultResp = resultResp;
            return params;
        }
    }

    /**
     * 战斗结果上报 返回
     */
    public static class CrossFightResultReportBack {
        public String roleUid;
        public int srvId;
        public byte fightType;
        public MixRes lostRes;
        public long protectTime;
        public EcResult<MinecraftMineAreaFightResultResp> r;

        public static CrossFightResultReportBack of(String roleUid,
                                                    int srvId,
                                                    byte fightType,
                                                    MixRes lostRes,
                                                    long protectTime,
                                                    EcResult<MinecraftMineAreaFightResultResp> r) {
            CrossFightResultReportBack back = new CrossFightResultReportBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.fightType = fightType;
            back.lostRes = lostRes;
            back.protectTime = protectTime;
            back.r = r;
            return back;
        }
    }

    /**
     * 领取挂机奖励 参数
     */
    public static class CrossGetHangRewardParams {
        public String roleUid;
        public int srvId;
        public int layer;
        public int tid;

        public static CrossGetHangRewardParams of(Role role, int layer, int tid) {
            CrossGetHangRewardParams params = new CrossGetHangRewardParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            params.layer = layer;
            params.tid = tid;
            return params;
        }
    }

    /**
     * 领取挂机奖励 返回
     */
    public static class CrossGetHangRewardBack {
        public String roleUid;
        public int srvId;
        public EcResult<MixRes> result;

        public static CrossGetHangRewardBack of(String roleUid, int srvId, EcResult<MixRes> result) {
            CrossGetHangRewardBack back = new CrossGetHangRewardBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.result = result;
            return back;
        }
    }

    /**
     * 矿点保护 参数
     */
    public static class CrossProtectPointParams {
        public String roleUid;
        public int srvId;

        public static CrossProtectPointParams of(Role role) {
            CrossProtectPointParams params = new CrossProtectPointParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            return params;
        }
    }

    /**
     * 矿点保护 返回
     */
    public static class CrossProtectPointBack {
        public String roleUid;
        public int srvId;
        public EcResult<Long> result;

        public static CrossProtectPointBack of(String roleUid, int srvId, EcResult<Long> result) {
            CrossProtectPointBack back = new CrossProtectPointBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.result = result;
            return back;
        }
    }

    /**
     * 放弃矿点 参数
     */
    public static class CrossGiveUpPointParams {
        public String roleUid;
        public int srvId;
        public int layer;
        public int tid;

        public static CrossGiveUpPointParams of(Role role, int layer, int tid) {
            CrossGiveUpPointParams params = new CrossGiveUpPointParams();
            params.roleUid = role.getUid();
            params.srvId = role.getGame().config.srvId;
            params.layer = layer;
            params.tid = tid;
            return params;
        }
    }

    /**
     * 放弃矿点 返回
     */
    public static class CrossGiveUpPointBack {
        public String roleUid;
        public int srvId;
        public int layer;
        public int tid;
        public EcResult<MixRes> result;

        public static CrossGiveUpPointBack of(String roleUid, int srvId, int layer, int tid, EcResult<MixRes> result) {
            CrossGiveUpPointBack back = new CrossGiveUpPointBack();
            back.roleUid = roleUid;
            back.srvId = srvId;
            back.layer = layer;
            back.tid = tid;
            back.result = result;
            return back;
        }
    }

    /**
     * 跨服通知添加邮件
     */
    public static class CrossAddMail {
        public String roleUid;
        public int srvId;
        public Mail mail;

        public static CrossAddMail of(String roleUid, int srvId, Mail mail) {
            CrossAddMail addMail = new CrossAddMail();
            addMail.roleUid = roleUid;
            addMail.srvId = srvId;
            addMail.mail = mail;
            return addMail;
        }
    }

    public static class MinecraftMergeMails {
        public List<CrossAddMail> mails;

        public static MinecraftMergeMails of(List<CrossAddMail> mails) {
            MinecraftMergeMails mmm = new MinecraftMergeMails();
            mmm.mails = mails;
            return mmm;
        }
    }

    /**
     * 跨服GM指令
     */
    public static class CrossGMCmd {
        public String roleUid;
        public int srvId;
        public CrossGMCmdType cmdType;
        public List<String> params;

        public static CrossGMCmd of(Role role, CrossGMCmdType cmdType, List<String> params) {
            CrossGMCmd cmd = new CrossGMCmd();
            cmd.roleUid = role.getUid();
            cmd.srvId = role.getGame().config.srvId;
            cmd.cmdType = cmdType;
            cmd.params = params;
            return cmd;
        }
    }
}
